package io.github.cubelitblade.librarymanagementbackend.service;

import io.github.cubelitblade.librarymanagementbackend.dto.UserBookRequestDTO;
import io.github.cubelitblade.librarymanagementbackend.entity.Book;
import io.github.cubelitblade.librarymanagementbackend.entity.FavoriteRecordView;
import io.github.cubelitblade.librarymanagementbackend.exception.BusinessException;
import io.github.cubelitblade.librarymanagementbackend.vo.BookBriefVO;
import io.github.cubelitblade.librarymanagementbackend.vo.FavoriteResponseVO;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;


@Service
public class UserFavoriteFacade {
    private final UserService userService;
    private final FavoriteService favoriteService;
    private final BookService bookService;

    UserFavoriteFacade(UserService userService, FavoriteService favoriteService, BookService bookService) {
        this.userService = userService;
        this.favoriteService = favoriteService;
        this.bookService = bookService;
    }

    /**
     * 将指定图书加入指定用户的收藏夹。
     *
     * @param userBookRequestDTO 包含用户ID和图书ID的请求对象。
     * @return 如果收藏成功，则返回包含收藏记录和图书简要信息的 {@link FavoriteResponseVO} 对象。
     * @throws BusinessException 当用户ID指定的用户不存在，图书ID指定的图书不存在或指定图书已经被指定用户收藏时。
     */
    public FavoriteResponseVO addToFavorites(UserBookRequestDTO userBookRequestDTO) {
        Integer userId = userBookRequestDTO.getUserId();
        Integer bookId = userBookRequestDTO.getBookId();

        if (!userService.existsUser(userId)) {
            throw BusinessException.userNotFound();
        }

        Book book = bookService.getById(bookId);
        if (book == null) {
            throw BusinessException.bookNotFound();
        }

        if (favoriteService.isFavorite(userId, bookId)) {
            throw BusinessException.favoriteRecordStatusConflict();
        }

        return FavoriteResponseVO.of(favoriteService.addToFavorites(userId, bookId), BookBriefVO.of(book));
    }

    /**
     * 将指定的收藏记录移除。
     *
     * @param favoriteRecordId 收藏记录ID。
     * @throws BusinessException 当收藏记录ID指定的收藏记录不存在时。
     */
    public void removeFromFavorites(Integer favoriteRecordId) {
        favoriteService.removeFromFavorites(favoriteRecordId);
    }

    /**
     * 查询指定用户的所有收藏记录。
     *
     * @param userId 用户ID。
     * @return 用户ID所指定用户的所有收藏记录。
     * @throws BusinessException 当用户ID所指定的用户不存在时。
     */
    public List<FavoriteResponseVO> listFavorites(Integer userId) {
        if (!userService.existsUser(userId)) {
            throw BusinessException.userNotFound();
        }

        return favoriteService.listFavorites(userId).stream().map(FavoriteResponseVO::of).collect(Collectors.toList());
    }

    /**
     * 查找指定用户收藏指定图书的记录。
     *
     * @param userId 用户ID。
     * @param bookId 图书ID。
     * @return 如果存在此记录，则包装为 {@link FavoriteResponseVO} 对象返回。
     * @throws BusinessException 当用户ID指定的用户不存在或图书ID指定的图书不存在时。
     */
    public FavoriteResponseVO getFavorite(Integer userId, Integer bookId) {
        if (!userService.existsUser(userId)) {
            throw BusinessException.userNotFound();
        }

        if (bookService.getById(bookId) == null) {
            throw BusinessException.bookNotFound();
        }

        FavoriteRecordView favoriteRecordView = favoriteService.getFavorite(userId, bookId);

        if (favoriteRecordView == null) {
            return null;
        }

        return FavoriteResponseVO.of(favoriteRecordView);
    }

    /**
     * 更改记录的 {@code active} 字段。
     *
     * @param favoriteRecordId 收藏记录的ID。
     * @return 更新后此记录的 {@code active} 字段的值。
     * @throws BusinessException 当记录不存在或数据库操作失败时。
     */
    public Boolean toggleFavoriteActive(Integer favoriteRecordId) {
        return favoriteService.toggleFavoriteActive(favoriteRecordId);
    }
}
